#include <iostream>
#include <unistd.h>
#include <string>
#include <pthread.h>
#include "Mutex.hpp"

using namespace std;

//pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER; // 全局锁

int ticket = 10000;

class ThreadData
{
public:
    ThreadData(const string &n, pthread_mutex_t &lock)
        :name(n), lockp(&lock)
    {}

    ~ThreadData() {}
    string name;
    pthread_mutex_t *lockp;
};

void* routine(void *args)
{
    ThreadData *td = (ThreadData*)args;
    while(1)
    {
        pthread_mutex_lock(td->lockp);
        //pthread_mutex_lock(&glock);
        if(ticket > 0)
        {
            cout << td->name << " sells ticket:" << ticket << endl;
            ticket--;
            pthread_mutex_unlock(td->lockp);
            //pthread_mutex_unlock(&glock);
            usleep(1000);
        }
        else 
        {
            pthread_mutex_unlock(td->lockp);
            //pthread_mutex_unlock(&glock);
            break;
        }
    }
    return 0;
}

int main()
{
    pthread_mutex_t lock;
    pthread_mutex_init(&lock, nullptr);

    pthread_t tid1, tid2, tid3, tid4; 
    
    ThreadData *td1 = new ThreadData("thread_1", lock);
    pthread_create(&tid1, nullptr, routine, (void*)td1);

    ThreadData *td2 = new ThreadData("thread_2", lock);
    pthread_create(&tid2, nullptr, routine, (void*)td2);

    ThreadData *td3 = new ThreadData("thread_3", lock);
    pthread_create(&tid3, nullptr, routine, (void*)td3);

    ThreadData *td4 = new ThreadData("thread_4", lock);
    pthread_create(&tid4, nullptr, routine, (void*)td4);
    
    pthread_join(tid1, nullptr);
    pthread_join(tid2, nullptr);
    pthread_join(tid3, nullptr);
    pthread_join(tid4, nullptr);

    pthread_mutex_destroy(&lock);
    return 0;
}